<?php
namespace Cache;

/**
 * @brief Yac缓存处理类
 */
class Yac {
    /** 
     * Yac实例
     *
     * @var object 
     */
    protected $handler;

    /** 
     * 缓存有效时间
     * 
     * @var int 
     */
    private $_expire;

    /**
     * 构造函数 
     * 
     * @note 生成Yac实例 
     * @param string $prefix 缓存变量名的前缀 
     * 
     * @return void
     */
    public function __construct($prefix = '') {
        if (!extension_loaded('yac')) {
            throw new \Exception('The yac extension must be loaded before use');
        }

        $config = \Yaf_Registry::get('Config');
        $this->_expire = $config->yac->expire;
        $this->handler = new \Yac($prefix);
    }

    /**
     * 设置缓存
     *
     * @param string $key 缓存变量名
     * @param mixed $value 数据
     * @param int $expire 有效时间
     * 
     * @return mixed
     */
    public function set($key, $value, $expire = 0) {
        $expire = ($expire === 0) ? $this->_expire : (int) $expire;
        return $this->handler->set($key, $value, $expire);
    }

    /**
     * 获取缓存
     *
     * @param string $key 缓存变量名
     * @param mixed $default 默认值
     * 
     * @return mixed
     */
    public function get($key, $default = null) {
        $value = $this->handler->get($key);
        return (false !== $value) ? $value : $default;
    }

    /**
     * 添加多个(键/值)
     *
     * @param array $key_vals 键/值数组
     * @param int $expire 有效时间
     * 
     * @return mixed
     */
    public function add($key_vals, $expire = 0) {
        if (is_array($key_vals)) {
            $expire = ($expire === 0) ? $this->_expire : (int) $expire;
            return $this->handler->add($key_vals, $expire);
        } else {
            return false;
        }
    }

    /**
     * 从缓存中删除存储的变量。如果指定了delay，则该值将在$delay秒后删除。
     *
     * @param array|string $keys
     * @param int $delay
     * 
     * @return mixed
     */
    public function delete($keys, $delay = 0) {
        return $this->handler->delete($keys, $delay);
    }

    /**
     * 清空缓存
     *
     * 立即使所有现有项目失效。
     * 它实际上并没有释放任何资源，它仅将所有项目标记为无效。
     *
     * @return mixed
     */
    public function flush() {
        return $this->handler->flush();
    }

    /**
     * 查看信息
     *
     * @param $key
     * 
     * @return mixed
     */
    public function info() {
        return $this->handler->info();
    }

    /**
     * 获取所有Key/Value信息
     * 
     * @return mixed
     */
    public function dump() {
        return $this->handler->dump();
    }

    /**
     * 获取所有Key
     * 
     * @return array
     */
    public function getAllKeys() {
        $data = $this->dump();
        if ($data) {
            $keys = array_column($data, 'key');
        }

        return $keys ?? [];
    }
}
